package jp.shuitic.hatebwebhook.twitter.web.client;

import java.util.ArrayList;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DecoratorPanel;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;

/**
 * GWTのGUI実装
 * @author shuitic.
 */
public class HatebWebHookTwit implements EntryPoint {

	/**
	 * Create a remote service proxy to talk to the server-side Greeting service.
	 */
	private final HatebTwitServiceAsync hatebTwitService = GWT
			.create(HatebTwitService.class);

	//入力画面
	private TextBox hatebUserField = new TextBox();
	private TextBox hatebHookKeyField = new TextBox();
	private TextBox twtUserName = new TextBox();
	private PasswordTextBox twtPass = new PasswordTextBox();
	private PasswordTextBox twtPassConfirm = new PasswordTextBox();
	private Label statusLabel = new Label();
	private Button resetButton = new Button("リセット");
	private Button updateButton = new Button("更新");
	private Button removeButton = new Button("データ削除");
	//ダイアログ
	private DialogBox dialogBox = new DialogBox();
	private Button closeButton = new Button("Close");
	private HTML dialogMessage = new HTML();

	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		// Create a table to layout the form options
	    FlexTable layout = new FlexTable();
	    layout.setCellSpacing(6);
	    FlexCellFormatter cellFormatter = layout.getFlexCellFormatter();

	    //入力こうもくの追加
	    layout.setHTML(0, 0, "<label>はてブid</label>");
	    layout.setWidget(0, 1, hatebUserField);
	    layout.setHTML(1, 0, "<label>はてブWeb Hook Key</label>");
	    layout.setWidget(1, 1, hatebHookKeyField);

	    layout.setHTML(2, 0, "<label>Twitter ID</label>");
	    layout.setWidget(2, 1, twtUserName);
	    layout.setHTML(3, 0, "<label>Twitter Pass</label>");
	    layout.setWidget(3, 1, twtPass);
	    layout.setHTML(4, 0, "<label>Twitter Pass(確認)</label>");
	    layout.setWidget(4, 1, twtPassConfirm);
	    //ボタンを横に配置する
	    HorizontalPanel hPanel = new HorizontalPanel();
	    hPanel.setSpacing(5); 
	    hPanel.add(removeButton);
	    hPanel.add(resetButton);
	    hPanel.add(updateButton);
	    layout.setWidget(5, 0, hPanel);
	    cellFormatter.setColSpan(5, 0, 2);
	    cellFormatter.setHorizontalAlignment(5, 0, HasHorizontalAlignment.ALIGN_CENTER);

	    layout.setWidget(6, 0, statusLabel);
	    cellFormatter.setColSpan(6, 0, 2);
	    cellFormatter.setHorizontalAlignment(6, 0, HasHorizontalAlignment.ALIGN_LEFT);
	    
	    //全体をDecoratorPanelにセットしてHTMLに埋め込む
	    DecoratorPanel decPanel = new DecoratorPanel();
	    decPanel.setWidget(layout);
		RootPanel.get("inputContainer").add(decPanel);

		
		//メッセージ表示用のダイアログを
		dialogBox.setText("メッセージ");
		dialogBox.setAnimationEnabled(true);
		closeButton.getElement().setId("closeButton");
		VerticalPanel dialogVPanel = new VerticalPanel();
		dialogVPanel.addStyleName("dialogVPanel");		
		dialogVPanel.add(dialogMessage);
		dialogVPanel.add(closeButton);
		dialogBox.setWidget(dialogVPanel);
		// Add a handler to close the DialogBox
		closeButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				dialogBox.hide();
			}
		});

		// Create a handler for the sendButton and nameField
		class ButtonClickHandler implements ClickHandler {
			/**
			 * Fired when the user clicks on the sendButton.
			 */
			public void onClick(ClickEvent event) {
				Button clickedBtn = (Button)event.getSource();
				if (clickedBtn.equals(resetButton)) {
					//リセットボタン
					resetData();
				} else if (clickedBtn.equals(updateButton)) {
					//更新ボタン
					updateData();
				} else if (clickedBtn.equals(removeButton)) {
					//削除ボタン
					removeData();
				}
			}

		}
		// Add a handler to send the name to the server
		ButtonClickHandler handler = new ButtonClickHandler();
		resetButton.addClickHandler(handler);
		removeButton.addClickHandler(handler);
		updateButton.addClickHandler(handler);
		
		showProcessDialog("取得中	", "データを取得しています");
		resetData();
	}

	/**
	 * データを削除します。
	 */
	private void removeData() {
		showProcessDialog("削除中	", "データを削除しています");
		hatebTwitService.removeHatebHookTwitUser( 
				new AsyncCallback<Boolean>() {
			public void onFailure(Throwable caught) {
				HatebWebHookTwitException ex = (HatebWebHookTwitException)caught;
				String title = "削除失敗";
				StringBuffer msg = new StringBuffer();
				msg.append("<h3>削除エラー</h3>");
				msg.append("<ul>");
				ArrayList<String> errMsgs = ex.getErrorMessages();
				for (String err: errMsgs) {
					msg.append("<li>");
					msg.append(err);
					msg.append("</li>");
				}
				msg.append("</ul>");
				showResultDialog(title, msg.toString());
				statusLabel.setText("エラー");
			}

			public void onSuccess(Boolean result) {
				hatebUserField.setText(null);
				hatebHookKeyField.setText(null);
				twtUserName.setText(null);
				twtPass.setText(null);
				twtPassConfirm.setText(null);
				String title = "削除処理成功";
				StringBuffer msg = new StringBuffer();
				if (result.booleanValue()) {
					msg.append("<h3>データを削除しました</h3>");
				} else {
					msg.append("<h3>データがありませんでした</h3>");
				}
				showResultDialog(title, msg.toString());
				statusLabel.setText("");
				resetButton.setVisible(false);
				removeButton.setVisible(false);
				updateButton.setText("登録");
			}
		});
		
	}

	/**
	 * データを更新します。
	 */
	private void updateData() {
		showProcessDialog("更新中	", "データを更新しています");
		if (validate()) {
			//データを更新する
			String hatebId = this.hatebUserField.getText();
			String hatebKey = this.hatebHookKeyField.getText();
			String twtId = this.twtUserName.getText();
			String twtpass = this.twtPass.getText();
	
			hatebTwitService.updateHatebHookTwitUser(hatebId, hatebKey, twtId, twtpass, 
					new AsyncCallback<HatebWebHookTwitUser>() {
				public void onFailure(Throwable caught) {
					HatebWebHookTwitException ex = (HatebWebHookTwitException)caught;
					String title = "更新失敗";
					StringBuffer msg = new StringBuffer();
					msg.append("<h3>更新エラー</h3>");
					msg.append("<ul>");
					ArrayList<String> errMsgs = ex.getErrorMessages();
					for (String err: errMsgs) {
						msg.append("<li>");
						msg.append(err);
						msg.append("</li>");
					}
					msg.append("</ul>");
					showResultDialog(title, msg.toString());
					statusLabel.setText("エラー");
				}

				public void onSuccess(HatebWebHookTwitUser result) {
					String title = "更新成功";
					StringBuffer msg = new StringBuffer();
					msg.append("<h3>データを更新しました</h3>");
					showResultDialog(title, msg.toString());
					statusLabel.setText("データを更新しました");
					resetButton.setVisible(true);
					removeButton.setVisible(true);
					updateButton.setText("更新");
				}
			});
		}
	}
	
	/**
	 * フィールドを検証し、エラーがある場合はダイアログを表示します。
	 * @return　
	 */
	private boolean validate() {
		ArrayList<String> errList = new ArrayList<String>();
		
		if (isEmpty(hatebUserField.getText())) {
			errList.add("はてブidを入力してください");
		}
		if (isEmpty(hatebHookKeyField.getText())) {
			errList.add("はてブWeb Hook Keyを入力してください");
		}
		if (isEmpty(twtUserName.getText())) {
			errList.add("Twitter IDを入力してください");
		}
		if (isEmpty(twtPass.getText())) {
			errList.add("Twitter Passを入力してください");
		}
		if (isEmpty(twtPassConfirm.getText())) {
			errList.add("Twitter Pass(確認)を入力してください");
		}
		if (!isEmpty(twtPass.getText()) && !isEmpty(twtPassConfirm.getText())) {
			if (!twtPass.getText().equals(twtPassConfirm.getText())) {
				errList.add("Twitter PassとTwitter Pass(確認)に入力したものが異なります");
			}
		}
		
		if (errList.size() == 0) {
			return true;
		} else {
			StringBuffer msg = new StringBuffer();
			msg.append("<h3>入力にエラーがあります</h3>");
			msg.append("<ul>");
			for (String err: errList) {
				msg.append("<li>");
				msg.append(err);
				msg.append("</li>");
			}
			msg.append("</ul>");
			String title = "入力エラー";
			showResultDialog(title, msg.toString());
			return false;
		}
		
	}
	
	private boolean isEmpty(String value) {
		if ((value == null) || (value.equals(""))) {
			return true;
		}
		return false;
	}
	
	/**
	 * サーバからデータを取得します。
	 */
	private void resetData() {
		showProcessDialog("取得中	", "データを取得しています");
		hatebTwitService.getHatebHookTwitUser( 
				new AsyncCallback<HatebWebHookTwitUser>() {
			public void onFailure(Throwable caught) {
				HatebWebHookTwitException ex = (HatebWebHookTwitException)caught;
				String title = "データ取得失敗";
				StringBuffer msg = new StringBuffer();
				msg.append("<h3>データ取得エラー</h3>");
				msg.append("<ul>");
				ArrayList<String> errMsgs = ex.getErrorMessages();
				for (String err: errMsgs) {
					msg.append("<li>");
					msg.append(err);
					msg.append("</li>");
				}
				msg.append("</ul>");
				showResultDialog(title, msg.toString());
				statusLabel.setText("エラー");
				resetButton.setVisible(false);
				removeButton.setVisible(false);
			}

			public void onSuccess(HatebWebHookTwitUser result) {
				closeButton.click();
				if (result == null) {
					hatebUserField.setText(null);
					hatebHookKeyField.setText(null);
					twtUserName.setText(null);
					twtPass.setText(null);
					twtPassConfirm.setText(null);
					statusLabel.setText("データが登録されていません。新規で登録します。");
					resetButton.setVisible(false);
					removeButton.setVisible(false);
					updateButton.setText("登録");
				} else {
					hatebUserField.setText(result.getHatebUserName());
					hatebHookKeyField.setText(result.getHatebWebHookKey());
					twtUserName.setText(result.getTwitterUserName());
					twtPass.setText(result.getTwitterPassword());
					twtPassConfirm.setText(result.getTwitterPassword());
					if (!result.isEnable()) {
						statusLabel.setText("Twitterのログインエラー等で使用が停止されています。情報を更新してください。");
					}
					statusLabel.setText("データを取得しました");
					resetButton.setVisible(true);
					removeButton.setVisible(true);
					updateButton.setText("更新");
				}
			}
		});
	}
	
	/**
	 * 結果メッセージダイアログを表示する
	 * @param title タイトル
	 * @param contentHtml コンテンツ
	 */
	private void showResultDialog(String title, String contentHtml) {
//		dialogBox.hide();
//		closeButton.click();
		dialogBox.setText(title);
		dialogMessage.setHTML(contentHtml);
		closeButton.setVisible(true);
		dialogBox.center();
		closeButton.setFocus(true);
	}
	
	/**
	 * 作業中ダイアログを表示する
	 * @param title タイトル
	 * @param msgText テキスト形式
	 */
	private void showProcessDialog(String title, String msgText) {
		dialogBox.setText(title);
		StringBuffer buf = new StringBuffer();
		buf.append("<b>");
		buf.append(msgText);
		buf.append("</b>");
		dialogMessage.setHTML(buf.toString());
		closeButton.setVisible(false);
		dialogBox.center();
	}

}
